import java.awt.BorderLayout;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;


public class Server_UDP extends JFrame {
    public  JTextField portField;
    public  JTextField saveDirField;
    public  JTextArea logArea;
    public int delay_attributes = 21;
    public int sync_attributes = 12;

    //创建Java GUI窗口
    public JPanel set_GUI()
    {
        setTitle("File_Server_UDP");
        setSize(800, 600);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setLocationRelativeTo(null);

        JPanel panel = new JPanel();
        panel.setLayout(new GridLayout(4, 2));

        panel.add(new JLabel("Port:"));
        portField = new JTextField("12345");
        panel.add(portField);

        panel.add(new JLabel("Save Directory:"));
        saveDirField = new JTextField();
        panel.add(saveDirField);
        
        return panel;
    }

//加入browse按钮
    public void browse_button(JPanel panel)
    {
        JButton browseButton = new JButton("Browse");
        panel.add(browseButton);
        browseButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                JFileChooser fileChooser = new JFileChooser();
                fileChooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
                int option = fileChooser.showOpenDialog(Server_UDP.this);
                if (option == JFileChooser.APPROVE_OPTION) {
                    File selectedDirectory = fileChooser.getSelectedFile();
                    saveDirField.setText(selectedDirectory.getAbsolutePath());
                }
            }
        });
    }

    //加入开启服务器按钮及控制台
    public void start_button(JPanel panel)
    {
       JButton startButton = new JButton("Start Server");
        panel.add(startButton);

        panel.add(new JLabel("Log"));
        logArea = new JTextArea();
        logArea.setEditable(false);
        JScrollPane scrollPane = new JScrollPane(logArea);

        JButton clearlogButton = new JButton("Clearlog");
        clearlogButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e)
            {
                logArea.setText("");
            }
        });
        panel.add(clearlogButton);

        add(panel, BorderLayout.NORTH);
        add(scrollPane, BorderLayout.CENTER);

        startButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                start_server();
                startButton.setEnabled(true);
            }
        });
    }

    private void start_server()
    {
        int port = Integer.parseInt(portField.getText());
        String saveDir = saveDirField.getText();
                new Thread(() -> {
                    int frenum = 0;
                    int DeviceID = 0;
                    InetAddress record = null;
                    
                    try(DatagramSocket socket = new DatagramSocket(port)){

                        while(true){

                        logArea.append("Server started on port " + port +", file recieved: " + frenum +"\n");
                        InetAddress SenderIp;
                        

                        byte[] fname = new byte[4096];
                        DatagramPacket fnamepacket = new DatagramPacket(fname,fname.length);  
                        socket.receive(fnamepacket);
                        SenderIp = fnamepacket.getAddress();
                        String IP=SenderIp.toString();
                        IP = IP.substring(IP.lastIndexOf("/") + 1 );
                        if(SenderIp != record)
                        {
                            DeviceID++;
                        }
                        logArea.append("senderip: " + SenderIp + "\n");

                        
                        String fileName_full = new String(fnamepacket.getData(), 0, fnamepacket.getLength()).trim();
                        String filename_forw = fileName_full.substring(0,fileName_full.lastIndexOf("."));
                        String filename_beh = fileName_full.substring(fileName_full.lastIndexOf("."),fileName_full.length());
                        filename_forw = filename_forw + "_"+ IP;
                        String fileName = filename_forw+filename_beh;
                        logArea.append("Filename: " + fileName + "\n");

                        String to_lowercase = fileName_full.toLowerCase();
                        int file_type = to_lowercase.indexOf("linkdelay", 0);

                        File saveFile = new File(saveDir, fileName);
                        logArea.append("File path: "+ saveFile.getPath()+"\n");

                        // 创建保存文件的目录
                        File dir = new File(saveDir);
                        if (!dir.exists()) {
                            dir.mkdirs();
                        }

                            try (FileOutputStream fos = new FileOutputStream(saveFile)) {

                                
                                int delay_filled = 0;
                                String[] delay_tuple = new String[delay_attributes];
                                int sync_filled = 0;
                                String[] sync_tuple = new String[sync_attributes];

                                if(file_type > 0  )
                                {
                                    delay_tuple[0] = String.valueOf(DeviceID);
                                    delay_filled++;
                                }
                                else
                                {
                                    sync_tuple[0]  = String.valueOf(DeviceID);
                                    sync_filled++;
                                }

                                
                                while(true)
                                {
                                byte[] buf = new byte[8192];
                                DatagramPacket packet = new DatagramPacket(buf, buf.length);
                                //socket.setSoTimeout(10000);
                                socket.receive(packet);

                                String data = new String(packet.getData(),"UTF-8").trim();
                                //logArea.append("data recieved: "+ data+"\n");
                                OutputStreamWriter os = new OutputStreamWriter(fos,"UTF-8");
                                if(!data.equals("EOF"))
                                {
                                os.write(data);
                                os.flush();
                                // write_in_database(data,file_type,delay_tuple,sync_tuple,delay_filled,sync_filled);
                                }
                                else
                                {
                                    logArea.append("File recieved done\n");
                                    os.flush();
                                    os.close();
                                    fos.close();
                                    frenum++;
                                    break;
                                }
                                }
                            }catch(FileNotFoundException fne)
                            {
                                logArea.append("File not found\n");
                            }
                            catch(IOException exception)
                            {
                                logArea.append("exception: " + exception.getMessage() + "\n");
                            }
                            record = SenderIp;
                        }
                    
                }catch(IOException se)
                {
                    logArea.append("se error: " + se.getMessage() + "\n");
                }
            }).start();
    }

    // private void write_in_database(String data, int file_type, String[] delay_tuple, String[] sync_tuple,int delay_filled,int  sync_filled)
    // {
    //     String driver = "com.mysql.cj.jdbc.Driver";
    //     String url = "jdbc:mysql://localhost:3306/sfm_database?useSSL=false";
    //     String user = "root";
    //     String password = "Cherry0930";

    //      if(file_type > 0)
    //      {

    //        Pattern pattern = Pattern.compile("(:| )\\d+(\\.)?(\\d)*");
    //        Matcher matcher = pattern.matcher(data);
    //        while (true) 
    //        {
    //         if(delay_filled < delay_attributes)
    //         {
    //             if(matcher.find())
    //             {
    //                 delay_tuple[delay_filled] = matcher.group().replace(":", "").trim();
    //                 System.out.println(delay_tuple[delay_filled]);
    //                 delay_filled++;
    //             }
    //             else
    //             break;
    //         }
    //         else
    //         {
    //             String sql = "INSERT INTO linkdelay_info (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)";
    //             try {

    //                  Class.forName(driver);
    //                  Connection conn = DriverManager.getConnection(url, user, password);
    //                  logArea.append("connect to linkdelay\n");
    //                  PreparedStatement stmt = (PreparedStatement) conn.prepareStatement(sql);

    //                  for (int i = 0;i < delay_attributes-1;i++) {
    //                     stmt.setInt(i, Integer.parseInt(delay_tuple[i]));
    //                  }
                
    //                  stmt.setFloat(delay_attributes,Integer.parseInt(delay_tuple[delay_attributes]));

    //             } 
    //             catch (ClassNotFoundException | NumberFormatException | SQLException e)
    //             {
    //                 System.out.println("error: "+ e.getMessage());
    //             }
    //             delay_filled = 0;
    //         }
    //        }
    //      }
    //      else
    //      {

    //        Pattern pattern = Pattern.compile("(:| )\\d+(\\.)?(\\d)*");
    //        Matcher matcher = pattern.matcher(data);
    //        while (true) 
    //        {
    //         if(sync_filled < sync_attributes)
    //         {
    //             if(matcher.find())
    //             {
    //                 sync_tuple[sync_filled] = matcher.group().replace(":", "").trim();
    //                 sync_filled++;
    //             }
    //             else
    //             break;
    //         }
    //         else
    //         {
    //             //将这些数据写入数据库
               
    //             String sql = "INSERT INTO sync_info (?,?,?,?,?,?,?,?,?,?,?,?)";
    //             try {

    //                  Class.forName(driver);
    //                  Connection conn = DriverManager.getConnection(url, user, password);
    //                  logArea.append("connect to sync\n");
    //                  PreparedStatement stmt = (PreparedStatement) conn.prepareStatement(sql);

    //                  for (int i = 0;i < sync_attributes-5;i++) {
    //                     stmt.setInt(i, Integer.parseInt(sync_tuple[i]));
    //                  }
    //                  for(int j = sync_attributes-5; j < sync_attributes- 1; j++)
    //                  {
    //                     stmt.setFloat(j,Float.parseFloat(sync_tuple[j]));
    //                  }
    //                  stmt.setInt(delay_attributes,Integer.parseInt(delay_tuple[delay_attributes]));

    //             }
    //             catch (ClassNotFoundException | NumberFormatException | SQLException e)
    //             {

    //             }
    //             sync_filled = 0;
    //         }
    //        }
    //      }        
    // }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> {
            Server_UDP server = new Server_UDP();
            server.setVisible(true);
            JPanel panel = server.set_GUI();
            server.browse_button(panel);
            server.start_button(panel);
        });
    }
    }
